﻿#include "ShareItemView.h"
#include <qtextcodec.h>
#include <qtwinextras/qwinfunctions.h>

inline bool hasAlpha(const QImage& image)
{
    const int w = image.width();
    const int h = image.height();
    for (int y = 0; y < h; ++y) {
        const QRgb* scanLine = reinterpret_cast<const QRgb*>(image.scanLine(y));
        for (int x = 0; x < w; ++x) {
            if (qAlpha(scanLine[x]) != 0)
                return true;
        }
    }
    return false;
}

template <typename Int>
inline Int pad4(Int v)
{
    return (v + Int(3)) & ~Int(3);
}

inline void initBitMapInfoHeader(int width, int height, bool topToBottom,
    DWORD compression, DWORD bitCount,
    BITMAPINFOHEADER* bih)
{
    memset(bih, 0, sizeof(BITMAPINFOHEADER));
    bih->biSize = sizeof(BITMAPINFOHEADER);
    bih->biWidth = width;
    bih->biHeight = topToBottom ? -height : height;
    bih->biPlanes = 1;
    bih->biBitCount = WORD(bitCount);
    bih->biCompression = compression;

    // 扫描线是字节对齐（RLE除外）
    const DWORD bytesPerLine = pad4(DWORD(width) * bitCount / 8);
    bih->biSizeImage = bytesPerLine * DWORD(height);
}

void getCapsImage(DibCaptureHelper& helper, QImage* image)
{
    HDC screenDevice = GetDC(nullptr);
    HDC hdc = CreateCompatibleDC(screenDevice);
    ReleaseDC(nullptr, screenDevice);

    const RECT& rect = helper.GetClientRect();

    const int w = rect.right - rect.left;
    const int h = rect.bottom - rect.top;

    BITMAPINFOHEADER bitmapInfo;
    initBitMapInfoHeader(w, h, false, BI_RGB, 32u, &bitmapInfo);
    DWORD* bits;

    HBITMAP winBitmap = CreateDIBSection(hdc, reinterpret_cast<BITMAPINFO*>(&bitmapInfo),
        DIB_RGB_COLORS, reinterpret_cast<VOID**>(&bits),
        nullptr, 0);
    HGDIOBJ oldhdc = static_cast<HBITMAP>(SelectObject(hdc, winBitmap));

    const HDC& captureHdc = helper.GetHdc();

    StretchBlt(hdc, 0, 0, w, h,
        captureHdc, 0, 0, w, h, SRCCOPY);

    *image = QtWin::imageFromHBITMAP(hdc, winBitmap, w, h);

    SelectObject(hdc, oldhdc); // 恢复状态
    DeleteObject(winBitmap);
    DeleteDC(hdc);
}

ShareItemView::ShareItemView(QWidget *parent)
    : QWidget(parent)
{
    ui.setupUi(this);
    ui.image->setAlignment(Qt::AlignCenter);
    setSelected(false);
}

void ShareItemView::setData(const Capturer& inData)
{
    _data = inData;
    
    DibCaptureHelper helper;

    _data.type = 2;
    helper.ChangeWindowHandle(_data);
    helper.Capture();

    // 取出窗口缩略图
    QImage image;
    getCapsImage(helper, &image);

    if (!hasAlpha(image))
    {
        _data.type = 0;
        helper.ChangeWindowHandle(_data);
        helper.Capture();
        getCapsImage(helper, &image);
    }

    _data.type = 1;
    _data.cursor = true;

    QPixmap pixmap = QPixmap::fromImage(image);
    pixmap = pixmap.scaled(QSize(172, 98), Qt::KeepAspectRatio, Qt::SmoothTransformation);
    QTextCodec* codec = QTextCodec::codecForName("GBK");
    ui.name->setText(codec->toUnicode(inData.name.c_str()));

    // 窗口缩略图
    ui.image->setPixmap(pixmap);
}

void ShareItemView::setSelected(bool inSelected)
{
    _selected = inSelected;

    if (_selected)
    {
        ui.background->setStyleSheet(QString::fromLocal8Bit("border:5px solid #3E80FF; border-radius:10px;"));
    }
    else
    {
        ui.background->setStyleSheet(QString::fromLocal8Bit("border:1px solid #EAEAEA; border-radius:10px;"));
    }

    ui.image->setStyleSheet(QString::fromLocal8Bit("border:0px;"));
    ui.name->setStyleSheet(QString::fromLocal8Bit("border:0px;"));
}

void ShareItemView::mousePressEvent(QMouseEvent* event)
{
    emit clicked(this);
}
